/*
-----------------------------------------------------------------------------
This file is part of escog.

Copyright (c) 2009 Jacob Essex

escog is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

escog is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with escog.  If not, see <http://www.gnu.org/licenses/>.
-----------------------------------------------------------------------------
*/
#ifndef __MAIN_H
#define __MAIN_H

#include <iostream>
#include <utility> //std::pair

#include <set>
#include <map>
#include <list>
#include <string>

#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>



#include "app.h"
#include "gui/gui.h"
#include "esm/esm.h"
#include "settings.h"



/**
* @brief converts a std::string to a wxString
*/
wxString toWX(const std::string& i);

#ifdef WIN32
std::string getRegKey(const std::string& pos, const std::string& name);
#endif


namespace fs = boost::filesystem;
class MainFrame: public GUIMain {
public:
    MainFrame(wxFrame *frame);
    ~MainFrame();

protected:

    Settings mSettings;

    typedef std::list<std::string> StringList;

    typedef std::list<ESM::FilePtr> FileList;
    typedef FileList::iterator FileListItr;
    typedef FileList::const_iterator FileListCItr;
    ///List of mods with loaded GMSTs
    FileList mMods;
    FileList mBase;
    ESM::FilePtr mEvilList;

    enum EvilAmount { EA_NOT, EA_ASBASE, EA_EVIL };

    /**
    * @brief returns the Evil amount of the mod
    */
    EvilAmount isEvil(ESM::RecordPtr r);

    void onCleanEvil( wxCommandEvent& event );

    /**
    * @brief called when the ini changes
    */
    void onIniChanged( wxFileDirPickerEvent& event );
    /**
    * @brief reloads the mod list. Seperated from onIniChanged so it can be locally called
    */
    void iniChanged();

    /**
    * @brief loads all mods in the MW Dir
    * @par the Morrowind directory
    */
    void loadMods(const std::string& dir);

    /**
    * @brief loads a single mod (GMSTs only) and inserts it into the given list
    * @par file the file to load, including path
    * @par a the list to add the files to
    * @return number of containing gmsts
    */
    int loadModToList(const std::string& file, std::list<ESM::FilePtr>& a);
    /**
    * @brief loads a given mod. GMSTs only
    * @par the file to load
    * @return the file pointer to the loaded mod
    */
    ESM::FilePtr loadMod(const std::string& file);

    /**
    * @return true if the file name matches Morrowind.esm Trib...
    */
    inline bool isBaseFile(const std::string& file) {
        return ( file == "Morrowind.esm" || file == "Tribunal.esm" || file == "Bloodmoon.esm" );
    }

    /**
    * @brief adds a given mod to the gui
    * @par name the name, without any path, of the file to add
    * @par hasGMSTs turns the item red if true
    */
    void addModToGUI(const std::string& name, bool hasGMSTs = false);


    /**
    * @brief called when show active gmsts is clicked
    */
    void onShowActive( wxCommandEvent& event );

    //hide this to save my hands
    typedef std::map<std::string, std::pair<ESM::RecordPtr,ESM::FilePtr> > ActiveGMSTMap;
    /**
    * @brief gets a list of active GMSTs
    */
    void getActiveGMSTs(bool everything = true, std::set<std::string> filter = std::set<std::string>());

    /**
    * @brief adds active gmsts to the list
    */
    void addActiveGMST(ActiveGMSTMap& active);

    void addGMST(ESM::RecordPtr r, ESM::FilePtr fp);

    void onModSelect( wxListEvent& event );

    void reloadActive();

    ESM::FilePtr getFile(const std::string& str);

    typedef std::list<std::pair<std::string, std::string> > GMSTFileList;

    void onRemoveSelected( wxCommandEvent& event );

    void removeFromFiles(std::map< std::string, std::list<std::string> >& om);

    /**
    * @par file the file to load
    * @par names the names of the GMST to remove
    */
    void removeGMSTs(const std::string& file, std::list<std::string>& names);


    void setSelectedMods(StringList& sl);

    std::list<std::string> getSelectedMods();

    GMSTFileList getSelectedGMSTs();

    wxString getCellValue(wxListCtrl* lc, long row, int col) {
        wxListItem     rowInfo;

        rowInfo.m_itemId = row;
        rowInfo.m_col = col;
        rowInfo.m_mask = wxLIST_MASK_TEXT;

        lc->GetItem( rowInfo );

        return rowInfo.m_text;
    }

    void checkFileColour(const std::string& file);

    void setItemColour(long row, wxColour c);

    /**
    * @return the path with only the file name
    */
    inline std::string getFileName(const std::string& path) {
        return fs::path(path).leaf();
    }
};

#endif // __MAIN_H
